; guard domain:
; Csaba Toth

(define (domain guard)
	(:requirements :strips :typing :adl :preferences)
	
	(:types
		t_burglar t_dog t_guard		- t_agent
		t_key t_ladder t_treasure	- t_item
		t_agent t_container			- t_inventory
		t_door t_floor				- t_stepable
		t_container t_door			- t_lockable
		t_phone t_vender			- t_operable
		t_camera t_container t_stepable t_phone t_switch t_vender - t_position
	)
	
	(:predicates
		(closed ?position - t_lockable)
		(locked ?position - t_lockable)
		(needs_key ?position - t_lockable ?item - t_key)
		(connected ?pos1 - t_position ?pos2 - t_position)
			; pos2 is directly reachablepos1
		(connectable ?pos1 - t_position ?pos2 - t_position)
			; pos2 is accessible from pos1 using ladders
		(agent_at_position ?agent - t_agent ?position - t_stepable)
		(contains ?object - t_inventory ?item - t_item)
	)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; actions:
;;
;;;; move_floor			- moves the selected agent from one stepable position 
;;;;						(door has been removed) to another if there is
;;;;						a connection between them with the right direction
;;;; move_door			- 
;;;; open				- opens an object
;;;; close				- closes a non stepable object, reverse of the open
;;;; unlock				- unlocks an object (stepable or not), reverse of lock
;;;; lock				- locks an object (stepable or not), reverse of unlock
;;;; pick_from_box		- the selected agent picks up a selected object 
;;;;						from the selected container
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	(:action move_floor
		:parameters
		(
			?agent		- t_agent 
			?old_pos	- t_stepable
			?new_pos	- t_floor
		)
		:precondition
		(and
			(agent_at_position ?agent ?old_pos)
			(connected ?old_pos ?new_pos)
		)
		:effect
		(and
			(agent_at_position ?agent ?new_pos)
			(not (agent_at_position ?agent ?old_pos))
		)
	)

	(:action move_door
		:parameters
		(
			?agent		- t_agent
			?old_pos	- t_stepable
			?new_pos	- t_door
		)
		:precondition
		(and
			(agent_at_position ?agent ?old_pos)
			(connected ?old_pos ?new_pos)
			(not (closed ?new_pos))
		)
		:effect
		(and
			(agent_at_position ?agent ?new_pos)
			(not (agent_at_position ?agent ?old_pos))
		)
	)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	(:action open
		:parameters
		(
			?agent		- t_agent
			?position	- t_stepable
			?object		- t_lockable
		)
		:precondition
		(and
			(agent_at_position ?agent ?position)
			(connected ?position ?object)
			(closed ?object)
			(not(locked ?object))
		)
		:effect
		(and
			(not (closed ?object))
		)
	)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	(:action close
		:parameters
		(
			?agent		- t_agent
			?position	- t_stepable
			?object		- t_lockable
		)
		:precondition
		(and
			(agent_at_position ?agent ?position)
			(connected ?position ?object)
			(not (closed ?object))
		)
		:effect
		(and
			(closed ?object)
		)
	)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	(:action unlock
		:parameters
		(
			?agent		- t_agent
			?position	- t_stepable
			?object		- t_lockable
			?item		- t_key
		)
		:precondition
		(and
			(agent_at_position ?agent ?position)
			(connected ?position ?object)
			(locked ?object)
			(contains ?agent ?item)
			(needs_key ?object ?item)
		)
		:effect
		(and
			(not (locked ?object))
		)
	)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	(:action lock
		:parameters
		(
			?agent		- t_agent
			?position	- t_stepable
			?object		- t_lockable
			?item		- t_key
		)
		:precondition
		(and
			(agent_at_position ?agent ?position)
			(connected ?position ?object)
			(not (locked ?object))
			(contains ?agent ?item)
			(needs_key ?object ?item)
		)
		:effect
		(and
			(locked ?object)
		)
	)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	(:action pick_from_box
		:parameters
		(
			?agent		- t_agent
			?position	- t_stepable
			?object		- t_container
			?item		- t_item
		)
		:precondition
		(and
			(agent_at_position ?agent ?position)
			(connected ?position ?object)
			(not (closed ?object))
			(contains ?object ?item)
		)
		:effect
		(and
			(not (contains ?object ?item))
			(contains ?agent ?item)
		)
	)
)

